home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / misc / worldmap / mapvu20 / mapview.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-01-11  |  45.5 KB  |  1,314 lines

  1. Program mapview; { program to view worldmap }
  2. { See MAPVIEW.DOC for complete documentation                                 }
  3.  
  4. { Copyright A.J. van den Bogert and Gisbert W.Selke Jan 1989                 }
  5.  
  6. {$UNDEF  DEBUG }                       { DEFINE while debugging }
  7.  
  8. {$IFDEF DEBUG }
  9. {$A+,R+,S+,I+,D+,F-,V-,B-,L+ }      { turn checking on while debugging }
  10. {$ELSE }
  11. {$A+,R-,S-,I+,D-,F-,V-,B-,L+ }
  12. {$ENDIF }
  13. {$M 65500,65500,560000}
  14.  
  15. {$IFDEF CPU87 }
  16. {$N+ }
  17. {$ELSE }
  18. {$N- }
  19. {$ENDIF }
  20.  
  21. Uses Crt, Dos, Graph, mapgraph, mapproj;
  22.  
  23. Const deflstext   = '.LST';     { default extension for list files }
  24.       defcmdext   = '.CMD';     { default extension for command files }
  25.       defpicext   = '.PIC';     { default extension for screen save files }
  26.       confname   ='MAPVIEW.CNF';{ configuration file name }
  27.       defpicname  ='SCREEN.PIC';{ default screen save file }
  28.       deflstname  = 'EMPTY.LST';{ default list file }
  29.       helpname   ='MAPVIEW.HLP';{ help file }
  30.       {$IFOPT N+ }
  31.       trigname    = 'TRIG3.BIN';{ precomputed trig values }
  32.       {$ELSE }
  33.       trigname    = 'TRIG2.BIN';{ precomputed trig values }
  34.       {$ENDIF }
  35.       defprinter  = 1;          { default printer port }
  36.       defaspcorr  = 1.0;        { default aspect ratio correction }
  37.       defbgcolour =   0;        { default background colour }
  38.       defgrcolour = -99;        { default grid       colour }
  39.       defbrcolour =  99;        { default border     colour }
  40.       defnrep     =   1;        { default number of overprintings }
  41.       noreal1     = 9999.9;     { dummy value }
  42.       noreal2     = 9999.0;     { ditto }
  43.       maxmpdir    = 15;         { maximum number of MPx default subdirs }
  44.       {$IFOPT N+ }
  45.       mpsize     =   25;        { size of a MP3 record - assumes 4-byte-reals }
  46.       mpmaxrec   = 1480;        { MP3 buffer array size   }
  47.       {$ELSE }
  48.       mpsize     =   37;        { size of a MP2 record - assumes 6-byte-reals }
  49.       mpmaxrec   = 1000;        { MP2 buffer array size   }
  50.       {$ENDIF }
  51.       mp0size     =  4;         { size of a MP0 record - assumes 2-byte-ints  }
  52.       mp0maxrec   =  9250;      { MP0 buffer array size   }
  53.       { The following equation must hold:                 }
  54.       { mpsize*mpmaxrec = mp0size*mp0maxrec }
  55.       banner    : string[11] = 'MAPVIEW 2.0';
  56.       copyright : string[9]  = 'Copyright';
  57.       author    : string[68] =
  58.      'A.J. van den Bogert, TapirSoft Gisbert W.Selke 08 Jan 1989';
  59.  
  60. Type mprec = Record
  61.                rectyp : byte;      { Record type: 1 is start of segment }
  62.                lon, lat : real;  { longitude and latitude }
  63.                merclat : real;   { Mercator function of latitude }
  64.                xg, yg, zg : real;{ globe coordinates }
  65.              End;
  66.      mp0rec = Record
  67.                 ilon, ilat : integer; { shifted lon/lat values }
  68.               End;
  69.      dirstr = string[63];
  70.      ftypes = (mpjunk, mp, mp0, mp1);
  71.  
  72. {$IFOPT N+ }
  73. Const mpext : Array [ftypes] Of string = ('.???', '.MP3', '.MP0', '.MP1');
  74. {$ELSE }
  75. Const mpext : Array [ftypes] Of string = ('.???', '.MP2', '.MP0', '.MP1');
  76. {$ENDIF }
  77.  
  78. Var
  79.  
  80. { INTERNAL USER-MODIFIABLE PARAMETERS:  }
  81.  screenfile : scrfile;
  82.  filename : string;                     { name of map file }
  83.  screenfilename : string;               { name of screen dump file }
  84.  printer : byte;                        { number of printer port }
  85.  gridlon, gridlat : real;               { grid intervals }
  86.  grid : boolean;                        { show grid? }
  87.  interact : boolean;                    { interactive or no?}
  88.  autoadapt : boolean;                   { always fill entire screen? }
  89.  showcmdline : boolean;                 { show command line? }
  90.  quit : boolean;                        { should we quit? }
  91.  userfinish : boolean;                  { user intervention? }
  92.  cmddir : dirstr;                       { default CMD file subdirectory }
  93.  lstdir : dirstr;                       { default LST file subdirectory }
  94.  picdir : dirstr;                       { default PIC file subdirectory }
  95.  mpdir : Array [1..maxmpdir] Of dirstr; { list of default MPx subdirectories }
  96.  mpdirct : byte;                        { number of MPx subdirectories }
  97.  
  98. { CONFIGURABLE PARAMETERS }
  99.  
  100.  aspcorr  : real;                       { aspect ratio correction }
  101.  grcolour : integer;                    { grid colour }
  102.  brcolour : integer;                    { border colour }
  103.  bgcolour : word;                       { background colour }
  104.  nrep     : byte;                       { number of overprintings for hardcopy }
  105.  
  106. { HIDDEN PARAMETERS }
  107.  inlin : string;                        { buffer for user input }
  108.  linptr : integer;                      { buffer pointer }
  109.  isnextreal, screenfileopen, directmp,  washeaperror : boolean;
  110.                                         { internal flags }
  111.  exitsave : pointer;                    { exit procedure pointer }
  112.  
  113. { WORKING VARIABLES }
  114. mpfile : File;
  115. mp1file : text;
  116. filetype : ftypes;
  117. mpbuf  : Array [1..mpmaxrec] Of mprec;
  118. mp0buf : Array [1..mp0maxrec] Of mp0rec Absolute mpbuf; { share memory loc }
  119. currec, maxrec : word;
  120. finish : boolean;
  121. nextreal, getpointx, getpointy : real;
  122.  
  123. {****** LOW LEVEL ROUTINES ******}
  124.  
  125. Procedure strip(Var lin : string);
  126. { strip leading and trailing blanks; convert to uppercase, too               }
  127.   Var i : byte;
  128. Begin                                                                { strip }
  129.   While (Length(lin) > 0) And (lin[1] = ' ') Do Delete(lin,1,1);
  130.   While (Length(lin) > 0) And (lin[Length(lin)] = ' ') Do
  131.                                                Delete(lin,Length(lin),1);
  132.   For i := 1 To Length(lin) Do lin[i] := UpCase(lin[i]);
  133. End;                                                                 { strip }
  134.  
  135. Function decomp(angle : real) : string;
  136. { decompose angle into degrees, minutes and seconds of arc; return as string }
  137.   Var rminu : real;
  138.       tempint : integer;
  139.       tempstr, res : string;
  140. Begin                                                               { decomp }
  141.   tempint := Trunc(angle);
  142.   str(tempint,res);
  143.   rminu:= 60.0 * Abs(angle - tempint);
  144.   tempint := Trunc(rminu);
  145.   str(tempint,tempstr);
  146.   If tempint < 10 Then tempstr := '0' + tempstr;
  147.   res := res + ':' + tempstr;
  148.   tempint := Round(60.0*(rminu- tempint));
  149.   str(tempint,tempstr);
  150.   If tempint < 10 Then tempstr := '0' + tempstr;
  151.   decomp := res + ':' + tempstr;
  152. End;                                                                { decomp }
  153.  
  154. Function prepend(ds, fs : string) : string;
  155. { prepend a directory string to a file name                                  }
  156. Begin                                                              { prepend }
  157.   If Pos(':',fs) > 0 Then Delete(fs,1,Pos(':',fs));
  158.   While (fs <> '') And (Pos('\',fs) > 0) Do Delete(fs,1,Pos('\',fs));
  159.   prepend := ds + fs;
  160. End;                                                               { prepend }
  161.  
  162. Function hasext(t : string) : boolean;
  163. { check if given file name has an extension included                         }
  164. Begin                                                               { hasext }
  165.   While Pos('\',t) > 0 Do Delete(t,1,Pos('\',t));
  166.   hasext := Pos('.',t) > 0;
  167. End;                                                                { hasext }
  168.  
  169. Procedure more;
  170. { DOS-like more prompt on text screen; sets userfinish True if Q, ESC, CTRL-C}
  171.   Var ch : char;
  172. Begin                                                                 { more }
  173.   GoToXY(50,25);
  174.   write('Hit any key to continue... ');
  175.   ch := UpCase(ReadKey);
  176.   userfinish := (ch = 'Q') Or (ch = ctrlc) Or (ch = esc);
  177. End;                                                                  { more }
  178.  
  179. Function getstring : string;
  180. { extract blank-terminated string from input buffer                          }
  181.   Var lt, ct : byte;
  182. Begin                                                            { getstring }
  183.   lt := Length(inlin);
  184.   While (linptr <= lt) And (inlin[linptr] = ' ') Do Inc(linptr);
  185.   ct := 1;
  186.   While (linptr+ct <= lt) And (inlin[linptr+ct] <> ' ') Do Inc(ct);
  187.   getstring := Copy(inlin,linptr,ct);
  188.   linptr := linptr + ct;
  189. End;                                                             { getstring }
  190.  
  191. Function instring(Var t : string; maxlg : byte) : boolean;
  192. { either read a string from the kbd or extract it from line buffer           }
  193. Begin                                                             { instring }
  194.   If interact Then instring := intext(t,maxlg)
  195.   Else Begin
  196.     t := getstring;
  197.     If Length(t) > maxlg Then delete(t,Succ(maxlg),255);
  198.     instring := True;
  199.   End;
  200. End;                                                              { instring }
  201.  
  202. Function getrealbuff : real;
  203. { extract blank-terminated real from input buffer                            }
  204.   Var tmp, tmp2 : real;
  205.       code, code2 : integer;
  206.       ipos : byte;
  207.       minus : boolean;
  208.       t : string;
  209. Begin                                                          { getrealbuff }
  210.   getrealbuff := noreal1;
  211.   t := getstring;
  212.   If t <> '' Then
  213.   Begin
  214.     ipos := Pos(':',t);
  215.     If ipos = 0 Then Val(t,tmp,code)
  216.     Else
  217.     Begin { read dd:mm:ss form; first a sign, if any, then dd: }
  218.       minus := t[1] = '-';
  219.       If minus Then
  220.       Begin
  221.         Delete(t,1,1);
  222.         Dec(ipos);
  223.       End;
  224.       Val(Copy(t,1,Pred(ipos)),tmp,code);
  225.       Delete(t,1,ipos);
  226.       If t <> '' Then
  227.       Begin { now mm }
  228.         ipos := Pos(':',t);
  229.         If ipos = 0 Then
  230.         Begin
  231.           Val(t,tmp2,code2);
  232.           tmp := tmp + tmp2/60.0;
  233.           code := code + code2;
  234.         End Else
  235.         Begin
  236.           Val(Copy(t,1,Pred(ipos)),tmp2,code2);
  237.           tmp := tmp + tmp2/60.0;
  238.           code := code + code2;
  239.           Delete(t,1,ipos);
  240.           If t <> '' Then
  241.           Begin  { now ss, possibly with decimals }
  242.             Val(t,tmp2,code2);
  243.             tmp := tmp + tmp2/3600.0;
  244.             code := code + code2;
  245.           End;
  246.         End;
  247.       End;
  248.       If minus Then tmp := -tmp;
  249.     End;
  250.     If code = 0 Then getrealbuff := tmp
  251.                 Else errmsg('ERROR: real number expected');
  252.   End;
  253. End;                                                           { getrealbuff }
  254.  
  255. Function getreal : real;
  256. { get a real number, either interactively (as typed or via crosshair) or     }
  257. { from input buffer, if read from batch                                      }
  258.   Var y, xa, ya : real;
  259.       dummy, firstin : boolean;
  260. Begin                                                              { getreal }
  261.   isnextreal := False;
  262.   If interact Then
  263.   Begin
  264.     If intext(inlin,15) Then
  265.     Begin
  266.       inlin := inlin + ' ';
  267.       linptr := 1;
  268.       y := getrealbuff;
  269.     End Else
  270.     Begin
  271.       xa := getpointx;
  272.       ya := getpointy;
  273.       firstin := True;
  274.       getpoint(xa,ya,dummy,firstin,True);
  275.       invproject(xa,ya,nextreal,y);
  276.       If nextreal > noreal1 Then nextreal := noreal1;
  277.       isnextreal := True;
  278.     End;
  279.   End Else y := getrealbuff;
  280.   If y <= noreal1 Then getreal := y Else getreal := noreal1;
  281. End;                                                               { getreal }
  282.  
  283. Function getnextreal : real;
  284. { get 2nd real number of a coordinate pair                                   }
  285. Begin                                                          { getnextreal }
  286.   If isnextreal Then getnextreal := nextreal
  287.                 Else getnextreal := getreal;
  288. End;                                                           { getnextreal }
  289.  
  290. Function testlstfile(Var filnam : string) : boolean;
  291. { open a lst file; set filetype accordingly, and indicate success          }
  292.   Var dummylf : file;
  293.       ext : string;
  294.       ierr : word;
  295. Begin                                                          { testlstfile }
  296.   ext := filnam;
  297.   While Pos('.',ext) > 0 Do Delete(ext,1,Pos('.',ext));
  298.   If Copy(ext,1,2) = 'MP' Then testlstfile := False
  299.   Else
  300.   Begin
  301.     Assign(dummylf,filnam);
  302.     {$I- } Reset(dummylf); {$I+ }
  303.     ierr := IOResult;
  304.     If (ierr <> 0) And (lstdir <> '') Then
  305.     Begin
  306.       Assign(dummylf,prepend(lstdir,filnam));
  307.       {$I- } Reset(dummylf); {$I+ }
  308.       ierr := IOResult;
  309.       If ierr = 0 Then filnam := prepend(lstdir,filnam);
  310.     End;
  311.     If ierr = 0 Then Close(dummylf);
  312.     testlstfile := ierr = 0;
  313.   End;
  314. End;                                                           { testlstfile }
  315.  
  316. Function openmpfile(filnam : string) : boolean;
  317. { open a map file; set filetype accordingly, and indicate success            }
  318.   Var ft : ftypes;
  319.       ts : string;
  320.  
  321.   Function foundfile(Var fs : string) : boolean;
  322.   { try to find file in various subdirectories                               }
  323.     Var dummymf : file;
  324.         i : byte;
  325.   Begin                                                          { foundfile }
  326.     Assign(dummymf,fs);
  327.     {$I- } Reset(dummymf); {$I+ }
  328.     If IOResult = 0 Then
  329.     Begin
  330.       Close(dummymf);
  331.       foundfile := True;
  332.       Exit;
  333.     End;
  334.     If (Pos(':',fs) = 0) And (Pos('\',fs) = 0) Then
  335.     Begin
  336.       For i := 1 To mpdirct Do
  337.       Begin
  338.         Assign(dummymf,prepend(mpdir[i],fs));
  339.         {$I- } Reset(dummymf); {$I+ }
  340.         If IOresult = 0 Then
  341.         Begin
  342.           Close(dummymf);
  343.           foundfile := True;
  344.           fs := prepend(mpdir[i],fs);
  345.           Exit;
  346.         End;
  347.       End;
  348.     End;
  349.     foundfile := False;
  350.   End;                                                           { foundfile }
  351.  
  352. Begin                                                           { openmpfile }
  353.   If hasext(filnam) Then
  354.   Begin
  355.     ts := Copy(filnam,Pos('.',filnam),4);
  356.     filetype := mpjunk;
  357.     For ft := mp To mp1 Do If ts = mpext[ft] Then filetype := ft;
  358.     Case filetype Of
  359.       mpjunk : Begin
  360.                  errmsg('Illegal map file extension ' + filnam);
  361.                  openmpfile := False;
  362.                End;
  363.       mp  : Begin
  364.               If foundfile(filnam) Then
  365.               Begin
  366.                 Assign(mpfile,filnam);
  367.                 reset(mpfile,mpsize);
  368.                 openmpfile := True;
  369.               End Else openmpfile := False;
  370.             End;
  371.       mp0 : Begin
  372.               If foundfile(filnam) Then
  373.               Begin
  374.                 Assign(mpfile,filnam);
  375.                 reset(mpfile,mp0size);
  376.                 openmpfile := True;
  377.               End Else openmpfile := False;
  378.             End;
  379.       mp1 : Begin
  380.               If foundfile(filnam) Then
  381.               Begin
  382.                 Assign(mp1file,filnam);
  383.                 reset(mp1file);
  384.                 SetTextBuf(mp1file,mpbuf);
  385.                 openmpfile := True;
  386.               End Else openmpfile := False;
  387.             End;
  388.     End;
  389.   End Else
  390.   Begin
  391.     If openmpfile(filnam+mpext[mp]) Then openmpfile := True
  392.       Else If openmpfile(filnam+mpext[mp0]) Then openmpfile := True
  393.         Else If openmpfile(filnam+mpext[mp1]) Then openmpfile := True
  394.           Else openmpfile := False;
  395.   End;
  396. End;                                                            { openmpfile }
  397.  
  398. Procedure getbin(Var binbuf : mprec);
  399. { read a set of coordinates; preprocess adequately, if necessary             }
  400. Begin                                                               { getbin }
  401.   If filetype = mp Then
  402.   Begin
  403.     If currec >= maxrec Then
  404.     Begin
  405.       BlockRead(mpfile,mpbuf,mpmaxrec,maxrec);
  406.       currec := 0;
  407.     End;
  408.     finish := maxrec = 0;
  409.     Inc(currec);
  410.     If Not finish Then binbuf := mpbuf[currec];
  411.   End Else
  412.   Begin
  413.     With binbuf Do
  414.     Begin
  415.       If filetype = mp0 Then
  416.       Begin
  417.         If currec >= maxrec Then
  418.         Begin
  419.           BlockRead(mpfile,mp0buf,mp0maxrec,maxrec);
  420.           currec := 0;
  421.         End;
  422.         finish := maxrec = 0;
  423.         Inc(currec);
  424.         If Not finish Then
  425.         Begin
  426.           With mp0buf[currec] Do
  427.           Begin
  428.             lon := ilon * 0.01;
  429.             If ilat < 20000 Then
  430.             Begin
  431.               lat := ilat * 0.01;
  432.               rectyp := 0;
  433.             End Else
  434.             Begin
  435.               lat := (ilat - 20000) * 0.01;
  436.               rectyp := 1;
  437.             End;
  438.           End;
  439.         End;
  440.       End Else
  441.       Begin
  442.         rectyp := currec;       { kludge to get rectyp 1 on 1st record, }
  443.         currec := 0;            { i.e., start new outline               }
  444.         Repeat
  445.           finish := eof(mp1file);
  446.           If Not finish Then readln(mp1file,inlin);
  447.           strip(inlin);
  448.           If inlin = '' Then rectyp := 1;
  449.         Until (inlin <> '') Or finish;
  450.         If finish Then
  451.         Begin
  452.           lat := noreal1;
  453.           lon := noreal1;
  454.         End Else
  455.         Begin
  456.           linptr := 1;
  457.           lat := getrealbuff;
  458.           lon := getrealbuff;
  459.         End;
  460.       End;
  461.       Case projtype Of
  462.         mercator, lambert : merclat := mercproj(lat);
  463.         ortho :    orthoproj(lon,lat,xg,yg,zg);
  464.         Else ;
  465.       End;
  466.     End;
  467.   End;
  468. End;                                                                { getbin }
  469.  
  470. Procedure closempfile;
  471. { close the appropriate map data file                                        }
  472. Begin                                                          { closempfile }
  473.   Case filetype Of
  474.     mp, mp0 : close(mpfile);
  475.     mp1 : close(mp1file);
  476.   End;
  477. End;                                                           { closempfile }
  478.  
  479. Procedure openscreenfile(temp : string);
  480. { if screen save file exists, open for append; if not, create it             }
  481.   Var picd : picdesc;
  482.       ios : word;
  483. Begin                                                       { openscreenfile }
  484.   If screenfileopen Then Close(screenfile);
  485.   screenfileopen := False;
  486.   Assign(screenfile,temp);
  487.   {$I- } Reset(screenfile,1); {$I+ }
  488.   If IOResult = 0 Then
  489.   Begin
  490.     BlockRead(screenfile,picd,SizeOf(picd),ios);
  491.     If ios = 0 Then screenfileopen := True
  492.     Else Begin
  493.       If (ios <> SizeOf(picd)) Or (picd.grdriver <> thisgraphdriver) Then
  494.                           errmsg('File ' + temp + ' has illegal format')
  495.       Else Begin
  496.         Seek(screenfile,FileSize(screenfile));
  497.         screenfileopen := True;
  498.       End;
  499.     End
  500.   End Else
  501.   Begin
  502.     {$I- } Rewrite(screenfile,1); {$I+ }
  503.     If IOResult = 0 Then screenfileopen := True
  504.                  Else errmsg('Cannot open file ' + temp + ' for screen saves');
  505.   End;
  506.   If screenfileopen Then screenfilename := temp;
  507. End;                                                        { openscreenfile }
  508.  
  509. {$F+ } Function heaperrorfunc(size : word) : integer; {$F- }
  510. { catch heap allocation errors, try to free memory, else return Nil pointer  }
  511. Begin                                                        { heaperrorfunc }
  512.   If fasttrig Then
  513.   Begin
  514.     dispotrigs;
  515.     heaperrorfunc := 2;
  516.   End
  517.   Else
  518.   Begin
  519.     heaperrorfunc := 1;
  520.     washeaperror := True;
  521.   End;
  522. End;                                                         { heaperrorfunc }
  523.  
  524. {****** BASIC GRAPHICS ROUTINES ******}
  525.  
  526. Procedure showdir(mask : string);
  527. { show DOS file directory                                                    }
  528.   Var sr : SearchRec;
  529.       ct : word;
  530. Begin                                                              { showdir }
  531.   ct := 0;
  532.   FindFirst(mask,ReadOnly+Hidden+Archive,sr);
  533.   While DosError = 0 Do
  534.   Begin
  535.     write(sr.Name:15,'   ');
  536.     Inc(ct);
  537.     If (ct Mod 4) = 0 Then writeln;
  538.     FindNext(sr);
  539.   End;
  540.   writeln;
  541. End;                                                               { showdir }
  542.  
  543. Procedure showprompt;
  544. { display a prompt, unless ...                                               }
  545. Begin                                                           { showprompt }
  546.   If showcmdline Then prompt('/ /a/c/d/e/g/h/l/m/n/p/q/s/w/x/z (? For help):')
  547.                  Else unprompt;
  548. End;                                                            { showprompt }
  549.  
  550.  
  551. {****** USER COMMANDS ******}
  552.  
  553. Procedure drawmap;
  554. { draw map using current parameter settings                                  }
  555.  
  556.   Var savcolour : word;
  557.       savlatmin, savlatmax : real;
  558.       itemp : longint;
  559.       ierr : integer;
  560.       listfile : text;
  561.       filnam, temp: string;
  562.       savshowcmdline : boolean;
  563.  
  564.  Procedure adjustlat;
  565.  { temporarily adjust latitude extremes                                      }
  566.  Begin                                                           { adjustlat }
  567.    savlatmin := latmin; savlatmax := latmax;
  568.    If projtype = mercator Then
  569.    Begin
  570.      latmin := rmax(latmin,-85.0);
  571.      latmax := rmin(latmax, 85.0);
  572.    End;
  573.    If Abs(latmax-latmin) < epsilon Then latmax := latmax + 1.0;
  574.  End;                                                            { adjustlat }
  575.  
  576.   Procedure getminmax(Var mylonmin, mylatmin, mylonmax, mylatmax : real);
  577.   { if MP0 or MP  file, find out which region this map covers                }
  578.     Var binbuf : mprec;
  579.   Begin                                                          { getminmax }
  580.     Case filetype Of
  581.       MP0 : Begin
  582.               getbin(binbuf);
  583.               mylonmin := binbuf.lon;
  584.               mylatmin := binbuf.lat;
  585.               getbin(binbuf);
  586.               mylonmax := binbuf.lon;
  587.               mylatmax := binbuf.lat;
  588.             End;
  589.       MP1 : Begin
  590.               mylonmin := -180.0;
  591.               mylatmin :=  -90.0;
  592.               mylonmax :=  180.0;
  593.               mylatmax :=   90.0;
  594.             End;
  595.       MP  : Begin
  596.               getbin(binbuf);
  597.               mylonmin := binbuf.lon;
  598.               mylatmin := binbuf.lat;
  599.               mylonmax := binbuf.merclat;
  600.               mylatmax := binbuf.xg;
  601.             End;
  602.     End;
  603.   End;                                                           { getminmax }
  604.  
  605.   Procedure drawonemap;
  606.   { draw a single map file                                                   }
  607.     Var ct : byte;
  608.         xo, yo, xn, yn : integer;
  609.         vis1, vis2 : boolean;
  610.         x2, y2, z2, dist, alpha, mylonmin, mylatmin, mylonmax, mylatmax : real;
  611.         binbuf : mprec;
  612.   Begin                                                         { drawonemap }
  613.     SetColor(colourglb);
  614.     ct := 0;
  615.     currec := 1; { kludge for MP1 files; cf getbin above }
  616.     If Not openmpfile(filnam) Then
  617.     Begin
  618.       errmsg('Map file ' + filnam + ' not found');
  619.       Exit;
  620.     End;
  621.     maxrec := 1; currec := 2;
  622.     getminmax(mylonmin,mylatmin,mylonmax,mylatmax);
  623.     If (mylonmin <= lonmax) And (mylonmax >= lonmin) And
  624.        (mylatmin <= latmax) And (mylatmax >= latmin) Then
  625.     Begin
  626.       getbin(binbuf);
  627.       While Not finish Do
  628.       Begin
  629.         Inc(ct);  { occasional overflow is what we want! }
  630.         With binbuf Do Begin
  631.           vis2 := (lon < lonmax) And (lon > lonmin) And
  632.                   (lat < latmax) And (lat > latmin);
  633.           If vis2 Then
  634.           Begin
  635.             x2 := 0.0; y2 := 0.0;
  636.             Case projtype Of
  637.               none :      Begin
  638.                             x2 := lon;
  639.                             y2 := lat;
  640.                           End;
  641.               mercator :  Begin
  642.                             vis2 := Abs(lat) <= 85.0;
  643.                             If vis2 Then
  644.                             Begin
  645.                               x2 := lon;
  646.                               y2 := merclat;
  647.                             End;
  648.                           End;
  649.               ortho :     Begin
  650.                             orthorot(xg,yg,zg,x2,y2,z2);
  651.                             vis2 := z2 > -epsilon;
  652.                           End;
  653.               lambert  : lambproj(lon,merclat,x2,y2);
  654.               azinorth : aziproj(lon,lat,x2,y2);
  655.               azisouth : aziproj(180.0-lon,-lat,x2,y2);
  656.               Else     project(lon,lat,x2,y2);  { for future extensions }
  657.             End; { Case }
  658.             xn := scalex(x2); yn := scaley(y2);
  659.             If (rectyp = 0) And vis1 And vis2 Then Line(xo,yo,xn,yn);
  660.           End;
  661.         End; { With }
  662.         If (ct = 0) And savshowcmdline Then showprogress(1);
  663.         xo := xn; yo := yn;
  664.         vis1 := vis2;
  665.         userfinish := checkuser;
  666.         getbin(binbuf);
  667.         finish := finish Or userfinish;
  668.       End;
  669.     End;
  670.     closempfile;
  671.     finish := userfinish;
  672.     SetColor(White);
  673.   End;                                                          { drawonemap }
  674.  
  675. Begin                                                              { drawmap }
  676.   savshowcmdline := showcmdline;
  677.   showcmdline := False;
  678.   showprompt;
  679.   If savshowcmdline Then showprogress(0);
  680.   checkwindow;
  681.   adjustlat;
  682.   mapborder(brcolour,savshowcmdline);
  683.   If grid Then drawgrid(gridlon,gridlat,grcolour,savshowcmdline);
  684.   If Not directmp Then
  685.   Begin
  686.     If Not testlstfile(filename) Then
  687.     Begin
  688.       errmsg('List file ' + filename + ' not found');
  689.       Exit;
  690.     End;
  691.     Assign(listfile,filename);
  692.     {$I- } reset(listfile); {$I+ }
  693.     finish := eof(listfile);
  694.   End Else finish := False;
  695.   While Not finish Do
  696.   Begin
  697.     savcolour := colourglb;
  698.     If directmp Then filnam := filename
  699.     Else Begin
  700.       readln(listfile,inlin);
  701.       strip(inlin);
  702.       linptr := 1;
  703.       filnam := getstring;
  704.       finish := filnam = 'END';
  705.       If (Not finish) And (filnam <> '') And (filnam[1] <> ';') Then
  706.       Begin
  707.         temp := getstring;
  708.         If temp <> '' Then
  709.         Begin
  710.           {$R- } Val(temp,itemp,ierr); {$IFDEF DEBUG } {$R+ } {$ENDIF }
  711.           If (ierr = 0) And (itemp >= 0) And (itemp <= maxcolour) Then
  712.                                                           colourglb := itemp;
  713.         End;
  714.       End;
  715.     End;
  716.     drawonemap;
  717.     colourglb := savcolour;
  718.     If directmp Then finish := True
  719.                 Else finish := finish Or eof(listfile);
  720.   End; { While }
  721.   If Not directmp Then Close(listfile);
  722.   latmin := savlatmin; latmax := savlatmax;
  723.   If (interact) Then
  724.   Begin
  725.     Sound(440);
  726.     Delay(200);
  727.     NoSound;
  728.   End;
  729.   If savshowcmdline Then showprogress(2);
  730.   showcmdline := savshowcmdline;
  731. End;                                                               { drawmap }
  732.  
  733. Procedure coordinates;
  734. { display coordinates of selected point                                      }
  735.   Var x, y : real;
  736.       lat, lon : real;
  737.       finish, firstin : boolean;
  738. Begin                                                          { coordinates }
  739.   lon := (lonmin + lonmax) * 0.5;
  740.   lat := (latmin + latmax) * 0.5;
  741.   firstin := True;
  742.   project(lon,lat,x,y);
  743.   prompt('Latitude: ' + decomp(lat) + ' / Longitude: ' + decomp(lon));
  744.   Repeat
  745.     If Not KeyPressed Then
  746.     Begin
  747.       invproject(x,y,lon,lat);
  748.       prompt('Latitude: ' + decomp(lat) + ' / Longitude: ' + decomp(lon));
  749.     End;
  750.     getpoint(x,y,finish,firstin,False);
  751.   Until finish;
  752.   unprompt;
  753. End;                                                           { coordinates }
  754.  
  755. Procedure setgrid;
  756. { set grid intervals or toggle grid display                                  }
  757.   Var x : real;
  758. Begin                                                              { setgrid }
  759.   If interact Then prompt('Enter latitude interval:');
  760.   x := getreal;
  761.   If x >= noreal2 Then grid := Not grid Else
  762.   Begin
  763.     If x >= 1.0 Then gridlat := x;
  764.     If interact Then prompt('Enter longitude interval:');
  765.     x := getnextreal;
  766.     If x > 1.0 Then gridlon := x;
  767.     unprompt;
  768.     grid := True;
  769.   End;
  770. End;                                                               { setgrid }
  771.  
  772. Procedure status;
  773. { display mode settings                                                      }
  774.   Var i : byte;
  775.       palette : palettetype;
  776. Begin                                                               { status }
  777.   preservescreen;
  778.   RestoreCRTMode;
  779.   write(banner);
  780.   {$IFOPT N+ }
  781.   writeln(' (coprocessor version)');
  782.   {$ELSE }
  783.   writeln(' (non-coprocessor version)');
  784.   {$ENDIF }
  785.   writeln;
  786.   write('Projection: ');
  787.   Case projtype Of
  788.     none     : writeln('None');
  789.     mercator : writeln('Mercator');
  790.     ortho    : writeln('Orthographic;  midpoint (lat/lon): ',
  791.                        decomp(midlat),'/',decomp(midlon));
  792.     lambert  : writeln('Lambert (conformal conical);  midpoint (lat/lon): ',
  793.                        decomp(midlat),'/',decomp(midlon));
  794.     azinorth : writeln('Azimuthal area preserving (north)');
  795.     azisouth : writeln('Azimuthal area preserving (south)');
  796.   End;
  797.   writeln('Window (lat/lon): ',decomp(latmin),'/',
  798.           decomp(lonmin),' .. ',decomp(latmax),'/',decomp(lonmax));
  799.   write('Grid intervals (lat/lon): ',decomp(gridlat),'/',decomp(gridlon));
  800.   If grid Then writeln(' (on)') Else writeln(' (off)');
  801.   write('Adaptive scaling ');
  802.   If autoadapt Then writeln('on') Else writeln('off');
  803.   If directmp Then writeln('Map file         : ',filename)
  804.               Else writeln('List of map files: ',filename);
  805.   writeln('Screen file      : ',screenfilename);
  806.   If fasttrig Then write('U') Else write('Not u');
  807.   writeln('sing fast trig table');
  808.   writeln;
  809.   GetPalette(palette);
  810.   With palette Do
  811.   Begin
  812.     If size > 1 Then
  813.     Begin
  814.       write('Colour palette:');
  815.       For i := 0 To Pred(size) Do write(' ',colors[i]);
  816.       writeln;
  817.     End;
  818.   End;
  819.   writeln('Current colours are (available: 0..',maxcolour,'):');
  820.   writeln('drawing: ',colourglb,'; grid: ',grcolour,'; border: ',brcolour,
  821.           '; background: ',bgcolour);
  822.   writeln;
  823.   writeln('Printer port     : ',printer,'; overprintings: ',nrep);
  824.   writeln;
  825.   writeln('Directories used for');
  826.   write('command files: current');
  827.   If cmddir <> '' Then write(', ',cmddir);
  828.   writeln;
  829.   write('   list files: current');
  830.   If lstdir <> '' Then write(', ',lstdir);
  831.   writeln;
  832.   write('picture files: current');
  833.   If picdir <> '' Then write(', ',picdir);
  834.   writeln;
  835.   write('    map files: current');
  836.   For i := 1 To mpdirct Do
  837.   Begin
  838.     write(', ');
  839.     If WhereX + Length(mpdir[i]) > 77 Then
  840.     Begin
  841.       writeln;
  842.       write(' ':15);
  843.     End;
  844.     write(mpdir[i]);
  845.   End;
  846.   writeln;
  847.   more;
  848.   restorescreen;
  849. End;                                                                { status }
  850.  
  851. Procedure help;
  852. { display help screen                                                        }
  853.   Var helpf : text;
  854.       helpline : string;
  855. Begin                                                                 { help }
  856.   preservescreen;
  857.   RestoreCRTMode;
  858.   Assign(helpf,helpname);
  859.   {$I- } Reset(helpf); {$I+ }
  860.   If IOResult <> 0 Then
  861.     writeln('Help file ',helpname,' not found. You''re on your own.')
  862.   Else Begin
  863.     userfinish := False;
  864.     While Not (EoF(helpf) Or userfinish) Do
  865.     Begin
  866.       If WhereY = 25 Then
  867.       Begin
  868.         more;
  869.         ClrScr;
  870.       End;
  871.       readln(helpf,helpline);
  872.       If Not userfinish Then writeln(helpline);
  873.     End;
  874.     Close(helpf);
  875.   End;
  876.   If Not userfinish Then more;
  877.   restorescreen;
  878. End;                                                                  { help }
  879.  
  880. Procedure setprojection;
  881. { set projection method and its parameters, if applicable                    }
  882.   Var xtemp : real;
  883.       temp : string;
  884. Begin                                                        { setprojection }
  885.   If interact Then prompt('Enter projection type (None, Mercator, ' +
  886.                           'Azimuthal, Orthographic, Lambert):');
  887.   Repeat Until instring(temp,1);
  888.   If temp = '' Then temp := ' ';
  889.   temp[1] := UpCase(temp[1]);
  890.   Case temp[1] Of
  891.     ' ',#13 : ; { ignore }
  892.     'N' : Begin
  893.             setprojtype(none);
  894.             If autoadapt Then adaptscale;
  895.           End;
  896.     'M' : Begin
  897.             setprojtype(mercator);
  898.             If autoadapt Then adaptscale;
  899.           End;
  900.     'O' : Begin
  901.             If interact Then prompt('Enter midpoint of latitude:');
  902.             xtemp := getreal;
  903.             If xtemp <= noreal2 Then
  904.             Begin
  905.               midlat := xtemp;
  906.               If interact Then prompt('Enter midpoint of longitude:');
  907.               xtemp := getnextreal;
  908.               If xtemp <= noreal2 Then midlon := xtemp;
  909.             End;
  910.             unprompt;
  911.             { calculate matrix elements }
  912.             setprojtype(ortho);
  913.           End;
  914.     'L' : Begin
  915.             If interact Then prompt('Enter midpoint of latitude:');
  916.             xtemp := getreal;
  917.             If xtemp <= noreal2 Then
  918.             Begin
  919.               midlat := xtemp;
  920.               If interact Then prompt('Enter midpoint of longitude:');
  921.               xtemp := getnextreal;
  922.               If xtemp <= noreal2 Then midlon := xtemp;
  923.             End;
  924.             unprompt;
  925.             setprojtype(lambert);
  926.           End;
  927.     'A' : setprojtype(azinorth);
  928.     Else errmsg('ERROR: unknown projection type');
  929.   End;
  930. End;                                                         { setprojection }
  931.  
  932. Procedure setcol;
  933. { set colour for drawing                                                     }
  934.   Var temp : string;
  935.       itemp : longint;
  936.       ierr : integer;
  937. Begin                                                               { setcol }
  938.   If interact Then prompt('Enter number of colour for subsequent plotting:');
  939.   Repeat Until instring(temp,2);
  940.   If temp <> '' Then
  941.   Begin
  942.     {$R- } Val(temp,itemp,ierr); {$IFDEF DEBUG } {$R+ } {$ENDIF }
  943.     If (ierr=0) And (itemp>=0) And (itemp<=maxcolour) Then colourglb := itemp
  944.                                                  Else errmsg('Illegal value');
  945.   End;
  946. End;                                                                { setcol }
  947.  
  948. Procedure setwindow;
  949. { set map window                                                             }
  950.   Var xtemp : real;
  951. Begin                                                            { setwindow }
  952.   If interact Then
  953.            prompt('Enter South West corner (latitude, or use cursor keys):');
  954.   project((2*lonmin+lonmax)/3,(2*latmin+latmax)/3,getpointx,getpointy);
  955.   xtemp := getreal;
  956.   If xtemp <= noreal2 Then
  957.   Begin
  958.     latmin := xtemp;
  959.     If interact Then prompt('Enter South West corner (longitude):');
  960.     xtemp := getnextreal;
  961.     If xtemp <= noreal2 Then lonmin := xtemp;
  962.   End;
  963.   If interact Then
  964.           prompt('Enter North East corner (latitude, or use cursor keys):');
  965.   project((lonmin+2*lonmax)/3,(latmin+2*latmax)/3,getpointx,getpointy);
  966.   xtemp := getreal;
  967.   If xtemp <= noreal2 Then
  968.   Begin
  969.     latmax := xtemp;
  970.     If interact Then prompt('Enter North East corner (longitude):');
  971.     xtemp := getnextreal;
  972.     If xtemp <= noreal2 Then lonmax := xtemp;
  973.   End;
  974.   If autoadapt Then adaptscale;
  975.   If (projtype = azinorth) Or (projtype = azisouth) Then setprojtype(projtype);
  976. End;                                                             { setwindow }
  977.  
  978. Procedure setfilelist;
  979. { set file from which to read map file names                                 }
  980.   Var temp : string;
  981.       extgiven : boolean;
  982.       namlgt : byte;
  983. Begin                                                          { setfilelist }
  984.   Repeat
  985.     If interact Then prompt('File name (? For available files):');
  986.     Repeat Until instring(temp,63);
  987.     unprompt;
  988.     If temp = '?' Then
  989.     Begin
  990.       preservescreen;
  991.       RestoreCRTMode;
  992.       writeln('Available list files:');
  993.       showdir('*'+deflstext);
  994.       If lstdir <> '' Then showdir(lstdir+'*'+deflstext);
  995.       more;
  996.       restorescreen;
  997.     End;
  998.   Until temp <> '?';
  999.   strip(temp);
  1000.   If temp <> '' Then
  1001.   Begin
  1002.     extgiven := hasext(temp);
  1003.     namlgt := Length(temp);
  1004.     If Not extgiven Then temp := temp + deflstext;
  1005.     If testlstfile(temp) Then
  1006.     Begin
  1007.       filename := temp;
  1008.       directmp := False;
  1009.     End Else
  1010.     Begin
  1011.       prompt('List file ' + temp + ' not found');
  1012.       Delay(1000);
  1013.       prompt('Trying to find a corresponding map file...');
  1014.       Delay(1000);
  1015.       If Not extgiven Then Delete(temp,Succ(namlgt),255);
  1016.       If openmpfile(temp) Then
  1017.       Begin
  1018.         directmp := True;
  1019.         filename := temp;
  1020.       End Else
  1021.       Begin
  1022.         prompt('No file ' + temp + ' found');
  1023.         Delay(1000);
  1024.       End;
  1025.     End;
  1026.   End;
  1027. End;                                                           { setfilelist }
  1028.  
  1029. Procedure setscreenfile;
  1030. { set file for screen saves                                                  }
  1031.   Var temp : string;
  1032. Begin                                                        { setscreenfile }
  1033.   If interact Then prompt('Enter name of file to save screens to:');
  1034.   Repeat Until instring(temp,63);
  1035.   unprompt;
  1036.   strip(temp);
  1037.   If (temp <> '') Then
  1038.   Begin
  1039.     If Pos('.',temp) = 0 Then temp := temp + defpicext;
  1040.     If (Pos(':',temp) = 0) And (Pos('\',temp) = 0) Then temp := picdir + temp;
  1041.     openscreenfile(temp);
  1042.   End;
  1043. End;                                                         { setscreenfile }
  1044.  
  1045. Procedure savetofile;
  1046. { handle screen file save                                                    }
  1047. Begin                                                           { savetofile }
  1048.   If Not screenfileopen Then openscreenfile(screenfilename);
  1049.   If screenfileopen Then save(screenfile);
  1050. End;                                                            { savetofile }
  1051.  
  1052. Procedure docommand;
  1053. { do a single command                                                        }
  1054.   Var cmd : char;
  1055.  
  1056.   Procedure execute;
  1057.   { execute file with commands                                               }
  1058.     Var savinteract : boolean;
  1059.         filnam, temp : string;
  1060.         cmdfile : text;
  1061.         ierr : word;
  1062.   Begin                                                            { execute }
  1063.     Repeat
  1064.       If interact Then
  1065.                prompt('Enter name of command file (? For available files):');
  1066.       Repeat Until instring(temp,63);
  1067.       unprompt;
  1068.       If temp = '?' Then
  1069.       Begin
  1070.         preservescreen;
  1071.         RestoreCRTMode;
  1072.         writeln('Available command files:');
  1073.         showdir('*'+defcmdext);
  1074.         If cmddir <> '' Then showdir(cmddir+'*'+defcmdext);
  1075.         more;
  1076.         restorescreen;
  1077.       End;
  1078.     Until temp <> '?';
  1079.     If temp <> '' Then
  1080.     Begin
  1081.       filnam := temp;
  1082.       If Pos('.',filnam) = 0 Then filnam := filnam + defcmdext;
  1083.       strip(filnam);
  1084.       Assign(cmdfile,filnam);
  1085.       {$I- } Reset(cmdfile); {$I+ }
  1086.       ierr := IOResult;
  1087.       If (ierr <> 0) And (cmddir <> '') Then
  1088.       Begin
  1089.         Assign(cmdfile,prepend(cmddir,filnam));
  1090.         {$I- } Reset(cmdfile); {$I+ }
  1091.         ierr := IOResult;
  1092.       End;
  1093.       If ierr <> 0 Then errmsg('Command file ' + filnam + ' not found')
  1094.       Else
  1095.       Begin
  1096.         savinteract := interact;
  1097.         interact := False;
  1098.         userfinish := False;
  1099.         While Not (eof(cmdfile) Or userfinish) Do
  1100.         Begin
  1101.           readln(cmdfile,inlin);
  1102.           docommand;
  1103.           userfinish := checkuser;
  1104.         End;
  1105.         Close(cmdfile);
  1106.         interact := savinteract;
  1107.       End;
  1108.     End;
  1109.   End;                                                             { execute }
  1110.  
  1111. Begin                                                            { docommand }
  1112.   inlin := ConCat(inlin,' ');
  1113.   linptr := 1;
  1114.   cmd := UpCase(inlin[linptr]);
  1115.   Inc(linptr);
  1116.   Case cmd Of
  1117.     '?' : help;
  1118.     ' ' : Begin showcmdline := Not showcmdline; showprompt; End;
  1119.     'A' : Begin autoadapt := Not autoadapt; If autoadapt Then adaptscale; End;
  1120.     'C' : setcol;
  1121.     'D' : drawmap;
  1122.     'E' : erasescreen;
  1123.     'G' : setgrid;
  1124.     'H' : Begin unprompt; scrprint(printer,nrep); End;
  1125.     'L' : setfilelist;
  1126.     'M' : status;
  1127.     'N' : setscreenfile;
  1128.     'P' : setprojection;
  1129.     'S' : savetofile;
  1130.     'W' : coordinates;
  1131.     'X' : execute;
  1132.     'Z' : setwindow;
  1133.     'Q', ctrlc, esc : If interact Then
  1134.                             quit := confirmquit('Do you really want to quit?')
  1135.                         Else quit := True;
  1136.     ';' : ;   { comment indicator in command files }
  1137.     #13 : ;   { ignore CR }
  1138.     Else errmsg('ERROR: unknown command');
  1139.   End;
  1140. End;                                                             { docommand }
  1141.  
  1142. {$F+ } Procedure exitmapview; {$F- }
  1143. { make sure we close graphics down, even in case of a runtime error          }
  1144. Begin                                                          { exitmapview }
  1145.   ExitProc := exitsave;
  1146.   If screenfileopen Then Close(screenfile);
  1147.   leavegraphic;
  1148.   If fasttrig Then dispotrigs;
  1149.   If washeaperror Then writeln('Not enough memory to run MapView properly');
  1150.   writeln(banner,'  --  ',author);
  1151.   writeln; writeln('Thanks for calling.');
  1152. End;                                                           { exitmapview }
  1153.  
  1154. Procedure initall;
  1155. { set initial values of user parameters                                      }
  1156.  
  1157.   Procedure readconf;
  1158.   { try to find .CNF file; if found, extract default info                    }
  1159.     Const maxpre = 12;
  1160.           availpre : Array [1..maxpre] Of string[3] =
  1161.     ('CMD','LST','PIC','MPX','MOD','ASP','GRC','BRC','BGC','PAL','OVP','PRN');
  1162.     Var cnf : text;
  1163.         palette : palettetype;
  1164.         i, npre : byte;
  1165.         pre : string;
  1166.         t : integer;
  1167.         t1 : shortint;
  1168.         tr : real;
  1169.  
  1170.     Function checkdir(t : string) : string;
  1171.     { make sure it's a valid directory string                                }
  1172.     Begin                                                         { checkdir }
  1173.       Delete(t,63,255);
  1174.       If t[Length(t)] <> '\' Then t := t + '\';
  1175.       checkdir := t;
  1176.     End;                                                          { checkdir }
  1177.  
  1178.   Begin                                                           { readconf }
  1179.     mpdirct := 0;
  1180.     cmddir := '';
  1181.     lstdir := '';
  1182.     picdir := '';
  1183.     Assign(cnf,confname);
  1184.     {$I- } Reset(cnf); {$I+ }
  1185.     If IOResult = 0 Then
  1186.     Begin
  1187.       While Not eof(cnf) Do
  1188.       Begin
  1189.         readln(cnf,inlin);
  1190.         strip(inlin);
  1191.         linptr := 1;
  1192.         pre := getstring;
  1193.         linptr := 4;
  1194.         npre := 0;
  1195.         For i := 1 To maxpre Do If pre = availpre[i] Then npre := i;
  1196.         If pre[1] = ';' Then npre := 99;
  1197.         Case npre Of
  1198.           0 : errmsg('Illegal specification ' + pre +
  1199.                      ' in configuration file');
  1200.          99 : ; { comment line }
  1201.           1 : cmddir := checkdir(getstring);
  1202.           2 : lstdir := checkdir(getstring);
  1203.           3 : picdir := checkdir(getstring);
  1204.           4 : Begin  { map files directories }
  1205.                 If mpdirct < maxmpdir Then
  1206.                 Begin
  1207.                   Inc(mpdirct);
  1208.                   mpdir[mpdirct] := checkdir(getstring);
  1209.                 End Else errmsg('Too many MPX lines in configuration file');
  1210.               End;
  1211.           5 : Begin  { non-standard graphics mode }
  1212.                 newgraphmode(Round(getrealbuff));
  1213.               End;
  1214.           6 : Begin  { aspect ratio correction for non-standard screens }
  1215.                 tr := getrealbuff;
  1216.                 If (tr > 0.0) And (tr <= noreal2) Then aspcorr := tr;
  1217.               End;
  1218.           7 : grcolour := Round(getrealbuff);   { grid colour }
  1219.           8 : brcolour := Round(getrealbuff);   { border colour }
  1220.           9 : bgcolour := Round(getrealbuff);   { background colour }
  1221.          10 : Begin  { set colour palette }
  1222.                 t := Round(getrealbuff);
  1223.                 tr := getrealbuff;
  1224.                 If (Round(tr) >= -127) And (Round(tr) <= 127)
  1225.                   Then t1 := Round(tr) Else tr := 127;
  1226.                 GetPalette(palette);
  1227.                 If (t1 >= 0) And (t1 <= maxcolour) And (t >= 0) And
  1228.                                  (t  <= palette.size) Then SetPalette(t,t1);
  1229.               End;
  1230.          11 : Begin  { set number of overprintings for hardcopy }
  1231.                 t := Round(getrealbuff);
  1232.                 If (t > 0) And (t <= 10) Then nrep := t;
  1233.               End;
  1234.          12 : Begin  { set number of printer port }
  1235.                 t := Round(getrealbuff);
  1236.                 If (t >= 1) And (t <= 4) Then printer := t;
  1237.               End;
  1238.         End;
  1239.       End;
  1240.       Close(cnf);
  1241.     End;
  1242.   End;                                                            { readconf }
  1243.  
  1244. Begin                                                              { initall }
  1245.   HeapError:= @heaperrorfunc;
  1246.   washeaperror := False;
  1247.   fasttrig     := False;
  1248.   exitsave := ExitProc;
  1249.   ExitProc := @exitmapview;
  1250.   initgraphic;
  1251.   If washeaperror Then Halt(1);
  1252.   printer  := defprinter;
  1253.   aspcorr  := defaspcorr;
  1254.   grcolour := defgrcolour;
  1255.   brcolour := defbrcolour;
  1256.   bgcolour := defbgcolour;
  1257.   nrep     := defnrep;
  1258.   readconf;
  1259.   readtrigs(trigname);
  1260.   washeaperror := False;
  1261.   If Abs(grcolour) > maxcolour Then grcolour := isignum(grcolour) * maxcolour;
  1262.   If Abs(brcolour) > maxcolour Then brcolour := isignum(brcolour) * maxcolour;
  1263.   If bgcolour > maxcolour Then bgcolour := maxcolour;
  1264.   If bgcolour < 0    Then bgcolour := 0;
  1265.   aspect := aspect * aspcorr;
  1266.   SetBkColor(bgcolour);
  1267.   filename := deflstname;
  1268.   screenfilename := picdir + defpicname;
  1269.   gridlon  := 20.0;
  1270.   gridlat  := 20.0;
  1271.  { set internal parameters }
  1272.   directmp := False;
  1273.   isnextreal := False;
  1274.   grid     := True;
  1275.   showcmdline := True;
  1276.   interact := True;
  1277.   autoadapt:= False;
  1278.   screenfileopen := False;
  1279.   quit     := False;
  1280. End;                                                               { initall }
  1281.  
  1282. { ****** MAIN PROGRAM ****** }
  1283. Begin                                                                 { main }
  1284.   {$IFDEF DEBUG }
  1285.     CheckBreak := True;
  1286.   {$ELSE }
  1287.     CheckBreak := False;
  1288.   {$ENDIF }
  1289.   initall;
  1290.   logo(banner,author);
  1291.   delay(2000);
  1292.   unprompt;
  1293.   mapborder(brcolour,False);
  1294.   drawgrid(gridlon,gridlat,grcolour,False);
  1295.   If ParamCount > 0 Then
  1296.   Begin
  1297.     inlin := 'X ' + ParamStr(1);
  1298.     interact := False;
  1299.     userfinish := False;
  1300.     docommand;
  1301.     interact := True;
  1302.   End;
  1303.   While Not quit Do
  1304.   Begin
  1305.     showprompt;
  1306.     inlin := '*';
  1307.     inlin[1] := ReadKey;
  1308.     unprompt;
  1309.     userfinish := False;
  1310.     docommand;
  1311.   End;
  1312.   { all closing stuff is done in exitmapview }
  1313. End.                                                                  { main }
  1314.